package org.song.service.impl;

import cn.hutool.core.lang.Assert;
import com.github.pagehelper.PageHelper;
import org.song.constant.NumberConstant;
import org.song.exception.myException.CommonException;
import org.song.mapper.BlogMapper;
import org.song.mapper.BlogTagMapper;
import org.song.mapper.TagMapper;
import org.song.model.dto.BlogDto;
import org.song.model.vo.Blog;
import org.song.model.vo.BlogTag;
import org.song.model.vo.Tag;
import org.song.service.BlogService;
import org.song.service.FileService;
import org.song.service.impl.common.AbstractBaseServiceImpl;
import org.song.util.SnowflakeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class BlogServiceImpl extends AbstractBaseServiceImpl implements BlogService {

    @Autowired( required = true )
    @Qualifier( value = "blogMapper")
    private BlogMapper blogMapper;

    @Autowired( required = true )
    @Qualifier( value = "blogTagMapper")
    private BlogTagMapper blogTagMapper;

    @Autowired( required = true )
    @Qualifier( value = "fileServiceImpl" )
    private FileService fileService;

    @Autowired( required = true )
    @Qualifier( value = "tagMapper" )
    private TagMapper tagMapper;

    /**
     * 查询所有博客信息
     * @param blogDto
     * @return
     */
    @NonNull
    @Override
    public List<Blog> listBlogs(@Validated @NonNull BlogDto blogDto) {
        // FIXME pageHelper分页插件提前分页问题
        PageHelper.startPage( blogDto.getPage() , blogDto.getSize() );
        final List<Blog> blogList = blogMapper.listBlogs(blogDto);
     //   Assert.isTrue( !CollectionUtils.isEmpty( blogList ) , () -> new CommonException("暂时未发布博客") );
        // 根据当前分页条数筛选集合
       // final int startIndex = (blogDto.getPage() - 1) * blogDto.getSize();
      //  final List<Blog> handlerBlogs = blogList.subList( startIndex , startIndex + blogDto.getSize() );
        blogList.stream().forEach( (blog ) -> {
            blog.setFirstPictureUrl( Optional.ofNullable( blog.getFirstPicture() )
                    .map( (firstPicture) -> fileService.getBlogMainImageFromOssByObjectName( firstPicture , null ) ).orElse( null )
            );
        } );
        return blogList;
    }

    /**
     * 根据博客信息删除指定博客
     * @param blog
     * @return
     */
    @NonNull
    @Override
    public Integer deleteBlog(@NonNull Blog blog) {
        Assert.isTrue(Objects.nonNull( blog.getId() ) , () ->  new CommonException( "删除博客错误,Id为空" ) );
        return blogMapper.deleteBlog(blog);
    }

    /**
     * 根据博客信息插入一条博客数据
     * @param blog
     * @return
     */
    @NonNull
    @Transactional( rollbackFor = {Exception.class} )
    @Override
    public Integer insertBlog(@NonNull Blog blog) {
        // 拿到博客的标签插入关联表
        // 当前插入博客的Id为空则为新增博客
        blog.setId( Optional.ofNullable( blog.getId() ).orElseGet( SnowflakeUtil::getNextLongId ) );
        blog.setFlag( Objects.equals( Blog.PublishStatusEnum.PUBLISHED.getCode() , blog.getPublished() )
                ? Blog.Flag.RELEASE.getCode() : Blog.Flag.DRAFT.getCode() );  // 博客编写状态设置为完结
        //TODO:设置博客的创建人从redis中获取
        blog.setCreatorId( 819877320899141987L );
        blog.setViews( NumberConstant.MIN_CODE.getLongCode() );
        blog.setThumbs( NumberConstant.MIN_CODE.getIntCode() );
        final BlogTag blogTag = BlogTag.builder().blogId( blog.getId() ).build();
        // 将博客对应标签插入到关联表
        final List<Tag> tagList = blog.getTags();
        blogTagMapper.deleteBlogTag( blogTag );
        tagList.forEach(tag -> {
            blogTag.setId( SnowflakeUtil.getNextLongId() );
            blogTag.setTagId( tag.getId() );
            blogTagMapper.insertBlogTag(blogTag);
        });
        // 由于插入博客和删除博客公用一个接口所以博客Id相同时为编辑博客，则执行修改操作不再继续添加新的博客
        return blogMapper.insertBlog(blog);
    }

    /**
     * 更新博客
     * @param blog
     * @return
     */
    @NonNull
    @Override
    public Integer updateBlog(@NonNull Blog blog) {
        return blogMapper.updateBlog(blog);
    }

    /**
     * 博客主页模糊搜索
     * @param queryParam
     * @return
     */
    @NonNull
    @Override
    public List<Blog> blurrySearchBlogs( @Nullable String queryParam ) {
        //TODO: 先从ES服务器搜索，没有则从数据库搜索
        if ( Objects.isNull( queryParam ) || StringUtils.isEmpty( StringUtils.trimAllWhitespace( queryParam ) ) ) {
            return Collections.emptyList();
        }
        // 先按照博客标题搜索，为空按照内容搜索
        final BlogDto blogDto = BlogDto.builder().title(queryParam).build();
        final List<Blog> blogList = blogMapper.listBlogs(blogDto);
        // TODO； 用户关键词搜索博客成功 将博客信息写回 ES 和 用户关键词记录
        if ( !CollectionUtils.isEmpty( blogList )  ){
            return blogList;
        }
        // 标题查询为空，按照描述摘要查询
        blogDto.setTitle( null );
        blogDto.setDescription( queryParam );
       return blogMapper.listBlogs(blogDto);
    }
}
